﻿#include <QLabel>
#include "CRobAlarmDlg.h"
#include <QThread>
#include "CHeader.h"
#include "CLogOper.h"
CRobAlarmDlg::CRobAlarmDlg(CRobCtrMange* pRobCtrMange, CDevDataBase* pDevData, QWidget *parent)
	: m_pRobCtrMange(pRobCtrMange),m_pDevDataRob(pDevData),QDialog(parent)
{
	ui.setupUi(this);
	m_sDevGuid = m_pDevDataRob->m_sDevGuid;
	m_nUpAlramCount = 0;
	setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
	//屏蔽回车键
	ui.pushButtonErrorReset->setAutoDefault(false);
	ui.pushButtonCancel->setAutoDefault(false);
	setStyleSheetFile();
	//配置定时器
	m_pTimer = new QTimer(this);
	m_pTimer->setTimerType(Qt::TimerType::PreciseTimer);
	connect(m_pTimer, &QTimer::timeout, this, &CRobAlarmDlg::slotDataRefresh);
	m_pTimer->start(1000);
	initConnect();
	m_pThread = NULL;
	/*m_pThread = new QThread();
	m_pAlarmTech = new CAlarmTech(m_sDevGuid);
	m_pAlarmTech->moveToThread(m_pThread);
	connect(m_pThread, SIGNAL(started()), m_pAlarmTech, SLOT(slot_ThreadWork()));
	m_pThread->start();*/
}

CRobAlarmDlg::~CRobAlarmDlg()
{
	//m_pAlarmTech->m_bThread = false;
	m_pTimer->stop();
	//m_pThread->quit();
	//if (!m_pThread->wait(5000))
	//{
	//	m_pThread->terminate();
	//}
	/*if (m_pAlarmTech)
	{
		delete m_pAlarmTech;
		m_pAlarmTech = nullptr;
	}*/

	if (m_pTimer)
	{
		delete m_pTimer;
		m_pTimer = nullptr;
	}
	if (m_pThread)
	{
		delete m_pThread;
		m_pThread = nullptr;
	}

}


void CRobAlarmDlg::setStyleSheetFile()
{
	QString sQssPath = ":/qss/styleSheet.css";
	QFile qss(sQssPath);
	qss.open(QFile::ReadOnly);
	this->setStyleSheet(qss.readAll());
}

void CRobAlarmDlg::initConnect()
{
	connect(ui.pushButtonErrorReset, &QPushButton::clicked, this, &CRobAlarmDlg::slotPushButtonErrorReset);
	connect(ui.pushButtonCancel, &QPushButton::clicked, this, &CRobAlarmDlg::slotPushButtonClose);
}

void CRobAlarmDlg::setAlarm(enumDeviceStatus enDeviceStatus, bool bIsAlarm)
{
	QLabel* pDeviceStatus = nullptr;

	QString strName = "label" + QString::number(enDeviceStatus);
	pDeviceStatus = findChild<QLabel *>(strName);

	//为空 返回
	if (nullptr == pDeviceStatus)
	{
		return;
	}

	//初始化动画绑定
	initAnima(enDeviceStatus, pDeviceStatus);
	//报警了
	if (true == bIsAlarm)
	{
		pDeviceStatus->setStyleSheet("min-width:20px;min-height:20px;"
			"max-width:20px;max-height:20px;"
			"border-radius:10px;border:1px solid black;"
			"background:rgb(255, 0, 0);");
		// 启动动画
		setAlarmAnima(m_mapAlarmAnima.value(enDeviceStatus).pAnimation);
		SRobAlarm stRobAlarm;
		stRobAlarm.m_eDeviceStatus = enDeviceStatus;
		stRobAlarm.m_sAlarmName = getErrLog(enDeviceStatus);
		stRobAlarm.m_dtAlarmTime = QDateTime::currentDateTime();
		addAlarm(stRobAlarm);
	}
	//取消报警
	else
	{
		pDeviceStatus->setStyleSheet("min-width:20px;min-height:20px;"
			"max-width:20px;max-height:20px;"
			"border-radius:10px;border:1px solid black;"
			"background:rgb(0, 255, 0);");
		// 关闭动画
		setNotAlarmAnima(m_mapAlarmAnima.value(enDeviceStatus).pAnimation);
		delAlarm(enDeviceStatus);
	}
}

void CRobAlarmDlg::initAnima(enumDeviceStatus enStatusStatus, QLabel* pBatteryStatus)
{
	//还没有绑定
	if (!m_mapAlarmAnima.contains(enStatusStatus))
	{
		// 创建 QGraphicsOpacityEffect 对象，并将其应用到 label 上
		QGraphicsOpacityEffect *effect = new QGraphicsOpacityEffect;
		pBatteryStatus->setGraphicsEffect(effect);
		effect->setOpacity(1.0); // 设置透明度为1.0
		// 创建动画对象
		QPropertyAnimation *animation = new QPropertyAnimation(effect, "opacity");
		structAlarmAnima sAlarmAnima;
		sAlarmAnima.pAnimation = animation;
		sAlarmAnima.pOpacity = effect;
		m_mapAlarmAnima.insert(enStatusStatus, sAlarmAnima);
	}
}

void CRobAlarmDlg::setAlarmAnima(QPropertyAnimation* pAnimation)
{
	pAnimation->stop();
	// 设置动画的起始值和结束值
	pAnimation->setStartValue(1.0);
	pAnimation->setEndValue(0.0);
	// 设置动画的持续时间和循环次数
	pAnimation->setDuration(500); // 1秒
	pAnimation->setLoopCount(-1); // 无限循环
	pAnimation->start();
}

void CRobAlarmDlg::setNotAlarmAnima(QPropertyAnimation* pAnimation)
{
	pAnimation->stop();
	// 设置动画的起始值和结束值
	pAnimation->setStartValue(0.99);
	pAnimation->setEndValue(1.0);
	// 设置动画的持续时间和循环次数
	pAnimation->setDuration(100); // 1秒
	pAnimation->setLoopCount(-1); // 一次
	pAnimation->start();
}

void CRobAlarmDlg::resetError()
{
	bool bExist = true;  //还存在控件
	int nIndex = 1;           //索引
	while (bExist)
	{
		if (35 == nIndex)
		{
			nIndex = 300;//后面扩展的序号是从300开始的
		}

		QString strName = "label" + QString::number(nIndex);
		QLabel *icon = findChild<QLabel *>(strName);
		if (nullptr == icon)
		{
			bExist = false;
			break;
		}
		setAlarm((enumDeviceStatus)nIndex, false);
		nIndex++;
	}
}

QString CRobAlarmDlg::getErrLog(enumDeviceStatus enStatusStatus)
{
	switch (enStatusStatus)
	{
	case 1:
		return A2T("RFID报警");
		break;
	case 2:
		return A2T("RFID通讯报警");
		break;
	case 3:
		return A2T("设备刚上电未校零报警");
		break;
	case 4:
		return A2T("急停被按下故障报警");
		break;
	case 5:
		return A2T("低压禁止充放电故障报警");
		break;
	case 6:
		return A2T("放电过流保护报警");
		break;
	case 7:
		return A2T("软件锁定MOS报警");
		break;
	case 8:
		return A2T("前端检测IC错误报警");
		break;
	case 9:
		return A2T("充电器通讯故障报警");
		break;
	case 10:
		return  A2T("充电过温保护报警");
		break;
	case 11:
		return  A2T("充电低温保护报警");
		break;
	case 12:
		return  A2T("充电过流保护报警");
		break;
	case 13:
		return  A2T("放电过温保护报警");
		break;
	case 14:
		return  A2T("放电低温保护报警");
		break;
	case 15:
		return  A2T("整组过压保护报警");
		break;
	case 16:
		return  A2T("整组欠压保护报警");
		break;
	case 17:
		return  A2T("电机报警");
		break;
	case 18:
		return  A2T("电机通讯故障报警");
		break;
	case 19:
		return  A2T("行走电机电流过大故障报警");
		break;
	case 20:
		return  A2T("行走电机力矩过大故障报警");
		break;
	case 21:
		return  A2T("到达前进限位故障报警");
		break;
	case 22:
		return  A2T("到达后退限位故障报警");
		break;
	case 23:
		return  A2T("单体过压保护报警");
		break;
	case 24:
		return  A2T("单体欠压保护报警");
		break;
	case 25:
		return  A2T("电池通讯故障报警");
		break;
	case 26:
		return  A2T("电池短路保护故障报警");
		break;
	case 27:
		return  A2T("电池低电量故障报警");
		break;
	case 28:
		return  A2T("电池电压异常报警");
		break;
	case 29:
		return  A2T("电池温度异常报警");
		break;
	case 30:
		return  A2T("电池过流报警");
		break;
	case 31:
		return A2T("电池模块故障报警");
		break;
	case 32:
		return A2T("短路保护报警");
		break;
	case 33:
		return A2T("升降电机报警");
		break;
	case 34:
		return A2T("冲洗异常");
		break;
	case 300:
		return A2T("非充电位长时间停留报警");
		break;
	case 301:
		return A2T("驱动电机温度过高故障");
		break;
	case 302:
		return A2T("升降电机温度过高故障");
		break;
	case 303:
		return A2T("循环充电失败");
		break;
	case 304:
		return A2T("前雷达避障报警");
		break;
	case 305:
		return A2T("后雷达避障报警");
		break;
	case 306:
		return A2T("云台避障报警");
		break;
	default:
		break;
	}
	return A2T("其他报警");
}

void CRobAlarmDlg::addAlarm(SRobAlarm stRobAlarm)
{
	if (!m_mapAlarm.contains(stRobAlarm.m_eDeviceStatus))
	{
		m_mapAlarm.insert(stRobAlarm.m_eDeviceStatus,stRobAlarm);
	}
}

void CRobAlarmDlg::delAlarm(enumDeviceStatus enRobAlarm)
{
	if (m_mapAlarm.contains(enRobAlarm))
	{
		SRobAlarm stAlarm = m_mapAlarm[enRobAlarm];
		SDevExecLog sDevExecLog;
		sDevExecLog.m_sDevName = A2T("机器人");
		sDevExecLog.m_sDescriptionl = stAlarm.m_sAlarmName+A2T("恢复");
		sDevExecLog.m_bExecResult = false;
		sDevExecLog.m_nAlarmLevel = enProcessAlarm;
		sDevExecLog.m_dLogTime = QDateTime::currentDateTime();
		m_pDevDataRob->addDevExecLog(sDevExecLog);
		m_mapAlarm.remove(enRobAlarm);
	}
}


void CRobAlarmDlg::slotDataRefresh()
{
	bool bUpAlarm = false;
	m_nUpAlramCount++;
	if (m_nUpAlramCount > 5)
	{
		bUpAlarm = true;
		m_nUpAlramCount = 0;
	}
	quint64 nErrCode = m_pDevDataRob->m_sDevStatus.toLongLong();
	if (0 != nErrCode)
	{
		QVector<bool> vecStatus;

		for (int i = 0; i < 48; i++)
		{
			bool nData = ((nErrCode >> i) & 1);//if(status & (1 << i)
			vecStatus.push_back(nData);
		}
		setAlarm(enAlarm17, vecStatus[40]);//电机报警
		setAlarm(enAlarm33, vecStatus[41]);//升降电机报警
		setAlarm(enAlarm28, vecStatus[42]);//电池电压异常 bit[2]
		setAlarm(enAlarm29, vecStatus[43]);//电池温度异常 bit[3]
		setAlarm(enAlarm30, vecStatus[44]);//电池过流报警 bit[4]
		setAlarm(enAlarm31, vecStatus[45]);//电池模块故障 bit[5]
		setAlarm(enAlarm26, vecStatus[46]);//电池短路保护故障 bit[6]
		setAlarm(enAlarm5, vecStatus[47]);//低压禁止充放电故障 bit[7]


		setAlarm(enAlarm1, vecStatus[32]);//RFID故障 bit[8]
		setAlarm(enAlarm3, vecStatus[33]);//设备刚上电未校零 bit[9]
		setAlarm(enAlarm304, vecStatus[34]);//前雷达避障报警 [34]
		setAlarm(enAlarm305, vecStatus[35]);//后雷达避障报警 [35]
		setAlarm(enAlarm4, vecStatus[38]);//急停被按下故障 bit[14]


		/**
		* @ Description:  40003 2个字节16-31
		*/
		setAlarm(enAlarm21, vecStatus[24]);//到达前进限位 bit[0]
		setAlarm(enAlarm22, vecStatus[25]);//到达后退限位 bit[1]
		setAlarm(enAlarm34, vecStatus[26]);//冲洗设备异常 bit[2]
		//setAlarm(enAlarm2, vecStatus[26]);//RFID通讯故障 bit[0]
		setAlarm(enAlarm18, vecStatus[27]);//电机通讯故障 bit[1]
		setAlarm(enAlarm9, vecStatus[28]);//充电器通讯故障 bit[0]
		setAlarm(enAlarm25, vecStatus[29]);//电池通讯故障 bit[1]
		setAlarm(enAlarm300, vecStatus[30]);//非充电位长时间停留[30]
		setAlarm(enAlarm303, vecStatus[31]);//循环充电失败[31]

		setAlarm(enAlarm19, vecStatus[16]);//行走电机电流过大故障
		setAlarm(enAlarm20, vecStatus[17]);//行走电机力矩过大故障
		setAlarm(enAlarm301, vecStatus[20]);//驱动电机温度过高故障[20]
		setAlarm(enAlarm302, vecStatus[21]);//升降电机温度过高故障[21]
		setAlarm(enAlarm306, vecStatus[22]);//云台避障报警 [22]

		/**
		* @ Description:  40004 0-15
		*/
		setAlarm(enAlarm23, vecStatus[8]);//单体过压保护
		setAlarm(enAlarm24, vecStatus[9]);//单体欠压保护
		setAlarm(enAlarm15, vecStatus[10]);//整组过压保护
		setAlarm(enAlarm16, vecStatus[11]);//整组欠压保护
		setAlarm(enAlarm10, vecStatus[12]);//充电过温保护
		setAlarm(enAlarm11, vecStatus[13]);//充电低温保护
		setAlarm(enAlarm13, vecStatus[14]);//放电过温保护
		setAlarm(enAlarm14, vecStatus[15]);//放电低温保护

		setAlarm(enAlarm12, vecStatus[0]);//充电过流保护
		setAlarm(enAlarm6, vecStatus[1]);//放电过流保护
		setAlarm(enAlarm32, vecStatus[2]);//短路保护
		setAlarm(enAlarm8, vecStatus[3]);//前段检测IC错误
		setAlarm(enAlarm7, vecStatus[4]);//软件锁定MOS
		setAlarm(enAlarm27, vecStatus[7]);//电池低电量故障

	}
	else
	{
		resetError();//复位错误
	}
	//写报警日志
	if (m_mapAlarm.size() > 0)
	{
		emit(sigAlarm(true));
		for (QMap<enumDeviceStatus, SRobAlarm>::iterator itor = m_mapAlarm.begin(); itor != m_mapAlarm.end(); itor++)
		{
			SRobAlarm stAlarm = itor.value();
			if (stAlarm.m_bIsWirteLog == false)
			{
				SDevExecLog sDevExecLog;
				sDevExecLog.m_sDevName = A2T("机器人");
				sDevExecLog.m_sDescriptionl = stAlarm.m_sAlarmName;
				sDevExecLog.m_bExecResult = false;
				sDevExecLog.m_nAlarmLevel = enProcessAlarm;
				sDevExecLog.m_dLogTime = stAlarm.m_dtAlarmTime;
				m_pDevDataRob->addDevExecLog(sDevExecLog);
				itor.value().m_bIsWirteLog = true;
			}
		}
	}
	else
	{
		emit(sigAlarm(false));
	}


	/**
	* @ Author: Gaojia
	* @ Description:
	*/
	if (bUpAlarm)
	{
		QVector<bool> vecStatus;

		for (int i = 0; i < 48; i++)
		{
			bool nData = ((nErrCode >> i) & 1);//if(status & (1 << i)
			vecStatus.push_back(nData);
		}


		//addFauitAlarm(enAlarm17, vecStatus[40]);//电机报警
		//addFauitAlarm(enAlarm33, vecStatus[41]);//升降电机报警
		//addFauitAlarm(enAlarm28, vecStatus[42]);//电池电压异常 bit[2]
		//addFauitAlarm(enAlarm29, vecStatus[43]);//电池温度异常 bit[3]
		//addFauitAlarm(enAlarm30, vecStatus[44]);//电池过流报警 bit[4]
		//addFauitAlarm(enAlarm31, vecStatus[45]);//电池模块故障 bit[5]
		//addFauitAlarm(enAlarm26, vecStatus[46]);//电池短路保护故障 bit[6]
		//addFauitAlarm(enAlarm5, vecStatus[47]);//低压禁止充放电故障 bit[7]


		//addFauitAlarm(enAlarm1, vecStatus[32]);//RFID故障 bit[8]
		//addFauitAlarm(enAlarm3, vecStatus[33]);//设备刚上电未校零 bit[9]
		//addFauitAlarm(enAlarm304, vecStatus[34]);//前雷达避障报警 [34]
		//addFauitAlarm(enAlarm305, vecStatus[35]);//后雷达避障报警 [35]
		//addFauitAlarm(enAlarm4, vecStatus[38]);//急停被按下故障 bit[14]

		///**
		//* @ Description:  40003 2个字节16-31
		//*/
		//addFauitAlarm(enAlarm21, vecStatus[24]);//到达前进限位 bit[0]
		//addFauitAlarm(enAlarm22, vecStatus[25]);//到达后退限位 bit[1]
		//addFauitAlarm(enAlarm34, vecStatus[26]);//冲洗设备异常 bit[2]
		////addFauitAlarm(enAlarm2, vecStatus[26]);//RFID通讯故障 bit[0]
		//addFauitAlarm(enAlarm18, vecStatus[27]);//电机通讯故障 bit[1]
		//addFauitAlarm(enAlarm9, vecStatus[28]);//充电器通讯故障 bit[0]
		//addFauitAlarm(enAlarm25, vecStatus[29]);//电池通讯故障 bit[1]
		//addFauitAlarm(enAlarm300, vecStatus[30]);//非充电位长时间停留[30]
		//addFauitAlarm(enAlarm303, vecStatus[31]);//循环充电失败[31]


		//addFauitAlarm(enAlarm19, vecStatus[16]);//行走电机电流过大故障
		//addFauitAlarm(enAlarm20, vecStatus[17]);//行走电机力矩过大故障
		//addFauitAlarm(enAlarm301, vecStatus[20]);//驱动电机温度过高故障[20]
		//addFauitAlarm(enAlarm302, vecStatus[21]);//升降电机温度过高故障[21]
		//addFauitAlarm(enAlarm306, vecStatus[22]);//云台避障报警 [22]

		///**
		//* @ Description:  40004 0-15
		//*/
		//addFauitAlarm(enAlarm23, vecStatus[8]);//单体过压保护
		//addFauitAlarm(enAlarm24, vecStatus[9]);//单体欠压保护
		//addFauitAlarm(enAlarm15, vecStatus[10]);//整组过压保护
		//addFauitAlarm(enAlarm16, vecStatus[11]);//整组欠压保护
		//addFauitAlarm(enAlarm10, vecStatus[12]);//充电过温保护
		//addFauitAlarm(enAlarm11, vecStatus[13]);//充电低温保护
		//addFauitAlarm(enAlarm13, vecStatus[14]);//放电过温保护
		//addFauitAlarm(enAlarm14, vecStatus[15]);//放电低温保护

		//addFauitAlarm(enAlarm12, vecStatus[0]);//充电过流保护
		//addFauitAlarm(enAlarm6, vecStatus[1]);//放电过流保护
		//addFauitAlarm(enAlarm32, vecStatus[2]);//短路保护
		//addFauitAlarm(enAlarm8, vecStatus[3]);//前段检测IC错误
		//addFauitAlarm(enAlarm7, vecStatus[4]);//软件锁定MOS
		//addFauitAlarm(enAlarm27, vecStatus[7]);//电池低电量故障

	}
}

void CRobAlarmDlg::slotPushButtonErrorReset()
{
	SDevExecLog sLog;
	sLog.m_dLogTime = QDateTime::currentDateTime();
	sLog.m_nAlarmLevel = enWorkInfo;
	sLog.m_sDescriptionl = A2T("%1点击了%2的%3按钮")
		.arg("admin")
		.arg(m_pDevDataRob->m_sRobName)
		.arg(A2T("报警复位"));
	sLog.m_sDevName = A2T("机器人远程操控");
	m_pDevDataRob->addDevExecLog(sLog);
	SCtrInfo stCtrInfo;
	stCtrInfo.m_sGuid = m_pDevDataRob->m_sDevGuid;
	stCtrInfo.m_nCtrCmd = enCResetAlarmEn;
	stCtrInfo.m_bCtrSync = true;
	stCtrInfo.m_bHasCtr = false;
	m_pRobCtrMange->ctrDevice(stCtrInfo);
}

void CRobAlarmDlg::slotPushButtonClose()
{
	this->close();
}


